001 /*
002 * Copyright 2005 Stephen J. McConnell.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.transit.console;
020
021 import java.io.IOException;
022 import java.io.OutputStream;
023 import java.io.File;
024 import java.io.FileNotFoundException;
025 import java.lang.reflect.InvocationTargetException;
026 import java.net.URI;
027 import java.net.URL;
028 import java.util.List;
029 import java.util.Set;
030 import java.util.HashSet;
031
032 import net.dpml.cli.Option;
033 import net.dpml.cli.Group;
034 import net.dpml.cli.CommandLine;
035 import net.dpml.cli.commandline.Parser;
036 import net.dpml.cli.util.HelpFormatter;
037 import net.dpml.cli.OptionException;
038 import net.dpml.cli.DisplaySetting;
039 import net.dpml.cli.builder.ArgumentBuilder;
040 import net.dpml.cli.builder.GroupBuilder;
041 import net.dpml.cli.builder.DefaultOptionBuilder;
042 import net.dpml.cli.builder.CommandBuilder;
043 import net.dpml.cli.validation.URIValidator;
044 import net.dpml.cli.validation.URLValidator;
045 import net.dpml.cli.validation.NumberValidator;
046
047 import net.dpml.util.Logger;
048 import net.dpml.lang.UnknownKeyException;
049 import net.dpml.lang.ValueDirective;
050
051 import net.dpml.lang.Part;
052 import net.dpml.lang.PartException;
053
054 import net.dpml.transit.Artifact;
055 import net.dpml.transit.Transit;
056 import net.dpml.transit.TransitBuilder;
057 import net.dpml.transit.DefaultTransitModel;
058 import net.dpml.transit.info.TransitDirective;
059 import net.dpml.transit.info.ProxyDirective;
060 import net.dpml.transit.info.CacheDirective;
061 import net.dpml.transit.info.HostDirective;
062 import net.dpml.transit.info.LayoutDirective;
063 import net.dpml.util.ExceptionHelper;
064
065
066 /**
067 * Transit Plugin that provides support for the configuration of the Transit subsystem.
068 *
069 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
070 * @version 1.0.0
071 */
072 public class TransitConsoleHandler
073 {
074 // ------------------------------------------------------------------------
075 // state
076 // ------------------------------------------------------------------------
077
078 private final Logger m_logger;
079 private final TransitDirective m_directive;
080 private final CommandLine m_line;
081 private final TransitDirectiveBuilder m_builder;
082
083 // ------------------------------------------------------------------------
084 // constructor
085 // ------------------------------------------------------------------------
086
087 /**
088 * Creation of a new Transit CLI handler.
089 *
090 * @param logger the assigned logging channel
091 * @param args command line arguments
092 * @exception Exception if an error occurs during plugin establishment
093 */
094 public TransitConsoleHandler( Logger logger, String[] args ) throws Exception
095 {
096 this( logger, getCommandLine( logger, args ) );
097 }
098
099 /**
100 * Creation of a new Transit CLI handler.
101 *
102 * @param logger the assigned logging channel
103 * @param line the command line
104 * @exception Exception if an error occurs during plugin establishment
105 */
106 private TransitConsoleHandler( final Logger logger, final CommandLine line ) throws Exception
107 {
108 if( null == line )
109 {
110 m_line = null;
111 m_directive = null;
112 m_builder = null;
113 m_logger = null;
114 System.exit( -1 );
115 }
116 else
117 {
118 m_logger = logger;
119 m_line = line;
120 m_directive = loadTransitDirective( line );
121 m_builder = new TransitDirectiveBuilder( m_directive );
122 if( null == m_directive )
123 {
124 System.exit( -1 );
125 }
126 }
127
128 // handle command
129
130 if( line.hasOption( INFO_COMMAND ) )
131 {
132 processInfo( line );
133 }
134 else if( line.hasOption( ADD_COMMAND ) )
135 {
136 TransitDirective directive = processAdd( line );
137 export( directive );
138 }
139 else if( line.hasOption( SET_COMMAND ) )
140 {
141 TransitDirective directive = processSet( line );
142 export( directive );
143 }
144 else if( line.hasOption( REMOVE_COMMAND ) )
145 {
146 TransitDirective directive = processRemove( line );
147 export( directive );
148 }
149 else if( line.hasOption( REVERT_COMMAND ) )
150 {
151 export( TransitDirective.CLASSIC_PROFILE );
152 }
153 else if( line.hasOption( LOAD_COMMAND ) )
154 {
155 processLoad( line );
156 }
157 else
158 {
159 processHelp();
160 }
161 }
162
163 // ------------------------------------------------------------------------
164 // command handling
165 // ------------------------------------------------------------------------
166
167 private void processLoad( CommandLine line )
168 {
169 try
170 {
171 URI uri = (URI) line.getValue( LOAD_COMMAND, null );
172 List list = line.getValues( ARGUMENTS );
173 String[] args = (String[]) list.toArray( new String[ list.size() ] );
174 Part part = Part.load( uri );
175 Object instance = part.instantiate( new Object[]{args} );
176 if( instance instanceof Runnable )
177 {
178 Runnable runnable = (Runnable) instance;
179 runnable.run();
180 }
181 }
182 catch( PartException e )
183 {
184 boolean stack = isDebugEnabled();
185 String message = ExceptionHelper.packException( e, stack );
186 System.out.println( message );
187 }
188 catch( Throwable e )
189 {
190 processException( e );
191 }
192 }
193
194 private void processException( Throwable e )
195 {
196 if( e instanceof InvocationTargetException )
197 {
198 InvocationTargetException ite = (InvocationTargetException) e;
199 Throwable cause = ite.getCause();
200 processException( cause );
201 }
202 else
203 {
204 final String error =
205 "Part exception.";
206 String message = ExceptionHelper.packException( error, e, true );
207 System.out.println( message );
208 }
209 }
210
211 private boolean isDebugEnabled()
212 {
213 return "true".equals( System.getProperty( "dpml.debug", "false" ) );
214 }
215
216 private void processInfo( CommandLine line )
217 {
218 StringBuffer buffer = new StringBuffer();
219
220 buffer.append( "\n\n Version " + Transit.VERSION );
221 buffer.append( "\n\n Environment\n" );
222 buffer.append( "\n ${dpml.home} \t" + Transit.DPML_HOME );
223 buffer.append( "\n ${dpml.data} \t" + Transit.DPML_DATA );
224 buffer.append( "\n ${dpml.prefs} \t" + Transit.DPML_PREFS );
225 buffer.append( "\n ${dpml.system} \t" + Transit.DPML_SYSTEM );
226
227 ProxyDirective proxy = m_directive.getProxyDirective();
228 if( null != proxy )
229 {
230 buffer.append( "\n\n Proxy Settings" );
231 buffer.append( "\n\n Host: \t" + proxy.getHost() );
232 if( proxy.getUsername() != null )
233 {
234 buffer.append( "\n Username: \t" + proxy.getUsername() );
235 }
236 char[] pswd = proxy.getPassword();
237 if( null != pswd )
238 {
239 buffer.append( "\n Password: \t" );
240 for( int i=0; i<pswd.length; i++ )
241 {
242 buffer.append( "*" );
243 }
244 }
245 String[] excludes = proxy.getExcludes();
246 if( excludes.length > 0 )
247 {
248 buffer.append( "\n Excludes: \t" );
249 for( int i=0; i<excludes.length; i++ )
250 {
251 String exclude = excludes[i];
252 buffer.append( exclude );
253 if( i < ( excludes.length-1 ) )
254 {
255 buffer.append( ", " );
256 }
257 }
258 }
259 }
260
261 CacheDirective cache = m_directive.getCacheDirective();
262
263 buffer.append( "\n\n Cache and System Settings\n" );
264 buffer.append( "\n Cache Layout: \t" + cache.getCacheLayout() );
265 buffer.append( "\n Cache Directory: \t" + cache.getCache() );
266 buffer.append( "\n System Directory: \t" + cache.getLocal() );
267 buffer.append( "\n System Layout: \t" + cache.getLocalLayout() );
268
269 HostDirective[] hosts = cache.getHostDirectives();
270 if( hosts.length > 0 )
271 {
272 buffer.append( "\n\n Host Settings" );
273 for( int i=0; i<hosts.length; i++ )
274 {
275 HostDirective host = hosts[i];
276 buffer.append( "\n\n " + host.getID() + " (" + ( i+1 ) + ")" );
277 buffer.append( "\n\n URL\t" + host.getHost() );
278 buffer.append( "\n Priority:\t" + host.getPriority() );
279 if( host.getIndex() != null )
280 {
281 buffer.append( "\n Index: \t" + host.getIndex() );
282 }
283 buffer.append( "\n Enabled: \t" + host.getEnabled() );
284 buffer.append( "\n Trusted: \t" + host.getTrusted() );
285 buffer.append( "\n Layout: \t" + host.getLayout() );
286 if( host.getUsername() != null )
287 {
288 buffer.append( "\n Username: \t" + host.getUsername() );
289 }
290 buffer.append( "\n Password: \t" );
291 char[] pswd = host.getPassword();
292 if( null != pswd )
293 {
294 for( int j=0; j<pswd.length; j++ )
295 {
296 buffer.append( "*" );
297 }
298 }
299 buffer.append( "\n Prompt: \t" + host.getPrompt() );
300 buffer.append( "\n Scheme: \t" + host.getScheme() );
301 }
302 }
303 else
304 {
305 buffer.append( "\n\n No hosts." );
306 }
307
308 LayoutDirective[] layouts = cache.getLayoutDirectives();
309 if( layouts.length > 0 )
310 {
311 buffer.append( "\n\n Layout Settings" );
312 for( int i=0; i<layouts.length; i++ )
313 {
314 LayoutDirective layout = layouts[i];
315 buffer.append( "\n\n " + layout.getID() + " (" + ( i+1 ) + ")" );
316 buffer.append( "\n\n Codebase:\t" + layout.getCodeBaseURI() );
317 buffer.append( "\n Title:\t" + layout.getTitle() );
318 }
319 }
320
321 System.out.println( buffer.toString() );
322 }
323
324 private TransitDirective processAdd( CommandLine line ) throws Exception
325 {
326 if( line.hasOption( ADD_HOST_COMMAND ) )
327 {
328 String key = (String) line.getValue( ADD_HOST_COMMAND, null );
329 CacheDirective cache = m_directive.getCacheDirective();
330 HostDirective[] hosts = cache.getHostDirectives();
331 for( int i=0; i<hosts.length; i++ )
332 {
333 HostDirective h = hosts[i];
334 if( h.getID().equals( key ) )
335 {
336 System.out.println( "ERROR: Host id '" + key + "' already assigned." );
337 return null;
338 }
339 }
340
341 System.out.println( "Adding host: " + key );
342 URL url = (URL) line.getValue( REQUIRED_HOST_OPTION, null );
343 String username = (String) line.getValue( USERNAME_OPTION, null );
344 String password = (String) line.getValue( PASSWORD_OPTION, null );
345 Number priority = (Number) line.getValue( HOST_PRIORITY_OPTION, new Integer( 100 ) );
346 String index = (String) line.getValue( HOST_INDEX_OPTION, null );
347 boolean enabled = !line.hasOption( DISABLED_OPTION );
348 boolean trusted = line.hasOption( TRUSTED_OPTION );
349 String layout = (String) line.getValue( LAYOUT_OPTION, "classic" );
350 String scheme = (String) line.getValue( HOST_SCHEME_OPTION, "" );
351 String prompt = (String) line.getValue( HOST_PROMPT_OPTION, "" );
352
353 HostDirective host =
354 new HostDirective(
355 key, priority.intValue(), url.toString(), index, username,
356 toCharArray( password ), enabled, trusted, layout,
357 scheme, prompt );
358
359 HostDirective[] newHosts = new HostDirective[ hosts.length + 1 ];
360 for( int i=0; i<hosts.length; i++ )
361 {
362 newHosts[i] = hosts[i];
363 }
364 newHosts[ hosts.length ] = host;
365 CacheDirectiveBuilder builder = new CacheDirectiveBuilder( cache );
366 CacheDirective newCache = builder.create( newHosts );
367 return m_builder.create( newCache );
368 }
369 else if( line.hasOption( ADD_LAYOUT_COMMAND ) )
370 {
371 String key = (String) line.getValue( ADD_LAYOUT_COMMAND, null );
372 CacheDirective cache = m_directive.getCacheDirective();
373 LayoutDirective[] handlers = cache.getLayoutDirectives();
374 for( int i=0; i<handlers.length; i++ )
375 {
376 LayoutDirective c = handlers[i];
377 if( c.getID().equals( key ) )
378 {
379 System.out.println( "ERROR: Layout id '" + key + "' already assigned." );
380 return null;
381 }
382 }
383
384 System.out.println( "Adding layout: " + key );
385 URI uri = (URI) line.getValue( REQUIRED_CODEBASE_OPTION, null );
386 String title = (String) line.getValue( TITLE_OPTION, null );
387
388 LayoutDirective handler =
389 new LayoutDirective(
390 key, title, uri, new ValueDirective[0] );
391
392 LayoutDirective[] newHandlers = new LayoutDirective[ handlers.length + 1 ];
393 for( int i=0; i<handlers.length; i++ )
394 {
395 newHandlers[i] = handlers[i];
396 }
397 newHandlers[ handlers.length ] = handler;
398 CacheDirectiveBuilder builder = new CacheDirectiveBuilder( cache );
399 CacheDirective newCache = builder.create( newHandlers );
400 return m_builder.create( newCache );
401 }
402 else
403 {
404 throw new IllegalStateException( "Unqualified add." );
405 }
406 }
407
408 private TransitDirective processSet( CommandLine line ) throws Exception
409 {
410 if( line.hasOption( SET_CACHE_COMMAND ) )
411 {
412 return setCache( line );
413 }
414 else if( line.hasOption( SET_SYSTEM_COMMAND ) )
415 {
416 return setSystem( line );
417 }
418 else if( line.hasOption( PROXY_COMMAND ) )
419 {
420 return setProxy( line );
421 }
422 else if( line.hasOption( SET_HOST_COMMAND ) )
423 {
424 return setHost( line );
425 }
426 else if( line.hasOption( SET_LAYOUT_COMMAND ) )
427 {
428 return setLayout( line );
429 }
430 else
431 {
432 throw new IllegalStateException( "Unqualified set command." );
433 }
434 }
435
436 private TransitDirective setCache( CommandLine line ) throws Exception
437 {
438 String cache = (String) line.getValue( DIRECTORY_OPTION );
439 String layout = (String) line.getValue( LAYOUT_OPTION );
440 CacheDirective directive = m_directive.getCacheDirective();
441 CacheDirectiveBuilder builder = new CacheDirectiveBuilder( directive );
442 CacheDirective newCache = builder.create( cache, layout, null, null );
443 return m_builder.create( newCache );
444 }
445
446 private TransitDirective setSystem( CommandLine line ) throws Exception
447 {
448 String system = (String) line.getValue( DIRECTORY_OPTION );
449 String layout = (String) line.getValue( LAYOUT_OPTION );
450 CacheDirective directive = m_directive.getCacheDirective();
451 CacheDirectiveBuilder builder = new CacheDirectiveBuilder( directive );
452 CacheDirective newCache = builder.create( null, null, system, layout );
453 return m_builder.create( newCache );
454 }
455
456 private TransitDirective setProxy( CommandLine line ) throws Exception
457 {
458 System.out.println( "Updating proxy configuration." );
459 ProxyDirective proxy = m_directive.getProxyDirective();
460
461 URL url = (URL) line.getValue( HOST_OPTION, null );
462 String username = (String) line.getValue( USERNAME_OPTION, null );
463 String password = (String) line.getValue( PASSWORD_OPTION, null );
464 List values = line.getValues( PROXY_EXCLUDE_OPTION );
465 String[] excludes = (String[]) values.toArray( new String[0] );
466 char[] pswd = toCharArray( password );
467 if( null == proxy )
468 {
469 if( null == url )
470 {
471 System.out.println( "ERROR: Missing proxy host option." );
472 return null;
473 }
474 ProxyDirective p = new ProxyDirective(
475 url.toString(), excludes, username, pswd );
476 return m_builder.create( p );
477 }
478 else
479 {
480 ProxyDirectiveBuilder builder = new ProxyDirectiveBuilder( proxy );
481 ProxyDirective p = builder.create( url, excludes, username, pswd );
482 return m_builder.create( p );
483 }
484 }
485
486 private TransitDirective setHost( CommandLine line ) throws Exception
487 {
488 String key = (String) line.getValue( SET_HOST_COMMAND, null );
489 CacheDirective cache = m_directive.getCacheDirective();
490 HostDirective[] hosts = cache.getHostDirectives();
491 HostDirective host = null;
492 for( int i=0; i<hosts.length; i++ )
493 {
494 HostDirective h = hosts[i];
495 if( h.getID().equals( key ) )
496 {
497 host = h;
498 }
499 }
500
501 if( null == host )
502 {
503 System.out.println( "ERROR: Host id '" + key + "' not recognized." );
504 return null;
505 }
506
507 System.out.println( "Updating host: " + key );
508 URL url = (URL) line.getValue( HOST_OPTION, null );
509 int priority = getPriorityValue( line );
510 String index = (String) line.getValue( HOST_INDEX_OPTION, null );
511 String username = (String) line.getValue( USERNAME_OPTION, null );
512 String password = (String) line.getValue( PASSWORD_OPTION, null );
513 boolean enabled = getEnabledFlag( line, host );
514 boolean trusted = getTrustedFlag( line, host );
515 String layout = (String) line.getValue( LAYOUT_OPTION, null );
516 String scheme = (String) line.getValue( HOST_SCHEME_OPTION, null );
517 String prompt = (String) line.getValue( HOST_PROMPT_OPTION, null );
518
519 HostDirectiveBuilder builder = new HostDirectiveBuilder( host );
520 HostDirective newHost =
521 builder.create(
522 priority, url, index, username, toCharArray( password ),
523 enabled, trusted, layout, scheme, prompt );
524
525 HostDirective[] newHosts = new HostDirective[ hosts.length ];
526 for( int i=0; i<hosts.length; i++ )
527 {
528 HostDirective h = hosts[i];
529 if( h.getID().equals( key ) )
530 {
531 newHosts[i] = newHost;
532 }
533 else
534 {
535 newHosts[i] = h;
536 }
537 }
538 CacheDirectiveBuilder cacheBuilder = new CacheDirectiveBuilder( cache );
539 CacheDirective newCache = cacheBuilder.create( newHosts );
540 return m_builder.create( newCache );
541 }
542
543 private TransitDirective setLayout( CommandLine line ) throws Exception
544 {
545 String key = (String) line.getValue( SET_LAYOUT_COMMAND, null );
546 CacheDirective cache = m_directive.getCacheDirective();
547 LayoutDirective[] handlers = cache.getLayoutDirectives();
548 LayoutDirective handler = null;
549 for( int i=0; i<handlers.length; i++ )
550 {
551 LayoutDirective c = handlers[i];
552 if( c.getID().equals( key ) )
553 {
554 handler = c;
555 }
556 }
557
558 if( null == handler )
559 {
560 System.out.println( "ERROR: Layout id '" + key + "' not recognized." );
561 return null;
562 }
563
564 System.out.println( "Updating layout: " + key );
565 URI uri = (URI) line.getValue( CODEBASE_OPTION, null );
566 String title = (String) line.getValue( TITLE_OPTION, null );
567
568 LayoutDirectiveBuilder builder = new LayoutDirectiveBuilder( handler );
569 LayoutDirective newDirective =
570 builder.create( title, uri, null );
571
572 LayoutDirective[] newDirectives = new LayoutDirective[ handlers.length ];
573 for( int i=0; i<handlers.length; i++ )
574 {
575 LayoutDirective d = handlers[i];
576 if( d.getID().equals( key ) )
577 {
578 newDirectives[i] = newDirective;
579 }
580 else
581 {
582 newDirectives[i] = d;
583 }
584 }
585 CacheDirectiveBuilder cacheBuilder = new CacheDirectiveBuilder( cache );
586 CacheDirective newCache = cacheBuilder.create( newDirectives );
587 return m_builder.create( newCache );
588 }
589
590 private TransitDirective processRemove( CommandLine line )
591 {
592 if( line.hasOption( SELECT_HOST_COMMAND ) )
593 {
594 String key = (String) line.getValue( SELECT_HOST_COMMAND, null );
595 System.out.println( "Removing resource host: " + key );
596 CacheDirective cache = m_directive.getCacheDirective();
597 CacheDirectiveBuilder builder = new CacheDirectiveBuilder( cache );
598 try
599 {
600 CacheDirective newCache = builder.removeHostDirective( key );
601 return m_builder.create( newCache );
602 }
603 catch( UnknownKeyException e )
604 {
605 System.out.println( "Unknown host '" + key + "'." );
606 return null;
607 }
608 }
609 else if( line.hasOption( SELECT_LAYOUT_COMMAND ) )
610 {
611 String key = (String) line.getValue( SELECT_LAYOUT_COMMAND, null );
612 System.out.println( "Removing layout: " + key );
613 CacheDirective cache = m_directive.getCacheDirective();
614 CacheDirectiveBuilder builder = new CacheDirectiveBuilder( cache );
615 try
616 {
617 CacheDirective newCache = builder.removeLayoutDirective( key );
618 return m_builder.create( newCache );
619 }
620 catch( UnknownKeyException e )
621 {
622 System.out.println( "Unknown layout '" + key + "'." );
623 return null;
624 }
625 }
626 else if( line.hasOption( REMOVE_PROXY_COMMAND ) )
627 {
628 if( null == m_directive.getProxyDirective() )
629 {
630 System.out.println( "Nothing to remove." );
631 return null;
632 }
633 else
634 {
635 System.out.println( "Removing all proxy settings." );
636 CacheDirective cache = m_directive.getCacheDirective();
637 return new TransitDirective( null, cache );
638 }
639 }
640 else
641 {
642 throw new IllegalStateException( "Unqualified remove command." );
643 }
644 }
645
646 private void export( TransitDirective directive )
647 {
648 if( null == directive )
649 {
650 return;
651 }
652 else if( m_directive.equals( directive ) )
653 {
654 System.out.println( "# no change" );
655 }
656 else
657 {
658 URI store = DefaultTransitModel.DEFAULT_PROFILE_URI;
659 URI uri = (URI) m_line.getValue( PROFILE_URI_OPTION, store );
660 System.out.println( "Saving to: " + uri );
661 OutputStream output = null;
662 try
663 {
664 URL url = buildURL( uri );
665 output = url.openConnection().getOutputStream();
666 TransitBuilder builder = new TransitBuilder( m_logger );
667 builder.write( directive, output );
668 }
669 catch( Exception e )
670 {
671 final String error =
672 "Internal error while attempting to write to the uri: "
673 + uri;
674 getLogger().error( error, e );
675 }
676 finally
677 {
678 if( null != output )
679 {
680 try
681 {
682 output.close();
683 }
684 catch( Exception e )
685 {
686 e.printStackTrace();
687 }
688 }
689 }
690 }
691 }
692
693 // ------------------------------------------------------------------------
694 // internal utilities
695 // ------------------------------------------------------------------------
696
697 private Logger getLogger()
698 {
699 return m_logger;
700 }
701
702 private char[] toCharArray( String value )
703 {
704 if( null == value )
705 {
706 return null;
707 }
708 else
709 {
710 return value.toCharArray();
711 }
712 }
713
714 private TransitDirective loadTransitDirective( CommandLine line )
715 {
716 if( line.hasOption( PROFILE_URI_OPTION ) )
717 {
718 URI uri = (URI) line.getValue( PROFILE_URI_OPTION, null );
719 try
720 {
721 URL url = buildURL( uri );
722 TransitBuilder builder = new TransitBuilder( m_logger );
723 return builder.load( url );
724 }
725 catch( FileNotFoundException e )
726 {
727 final String error =
728 "Resource not found: "
729 + uri;
730 getLogger().warn( error );
731 return null;
732 }
733 catch( Exception e )
734 {
735 final String error =
736 "An error occured while attempting to load the transit profile: "
737 + uri;
738 getLogger().error( error, e );
739 return null;
740 }
741 }
742 else
743 {
744 File prefs = Transit.DPML_PREFS;
745 File config = new File( prefs, "dpml/transit/xmls/standard.xml" );
746 if( config.exists() )
747 {
748 try
749 {
750 URL url = config.toURL();
751 TransitBuilder builder = new TransitBuilder( m_logger );
752 return builder.load( url );
753 }
754 catch( Exception e )
755 {
756 final String error =
757 "An error occured while attempting to load the transit profile: "
758 + config;
759 getLogger().error( error, e );
760 return null;
761 }
762 }
763 else
764 {
765 //
766 // load default profile
767 //
768
769 return TransitDirective.CLASSIC_PROFILE;
770 }
771 }
772 }
773
774 private URL buildURL( URI uri ) throws IOException
775 {
776 if( Artifact.isRecognized( uri ) )
777 {
778 return Artifact.createArtifact( uri ).toURL();
779 }
780 else
781 {
782 return uri.toURL();
783 }
784
785 }
786
787 private boolean getEnabledFlag( CommandLine line, HostDirective host )
788 {
789 if( line.hasOption( DISABLED_OPTION ) )
790 {
791 return false;
792 }
793 else if( line.hasOption( ENABLED_OPTION ) )
794 {
795 return true;
796 }
797 else
798 {
799 return host.getEnabled();
800 }
801 }
802
803 private boolean getTrustedFlag( CommandLine line, HostDirective host )
804 {
805 if( line.hasOption( TRUSTED_OPTION ) )
806 {
807 return true;
808 }
809 else if( line.hasOption( UNTRUSTED_OPTION ) )
810 {
811 return false;
812 }
813 else
814 {
815 return host.getTrusted();
816 }
817 }
818
819 private int getPriorityValue( CommandLine line )
820 {
821 if( line.hasOption( HOST_PRIORITY_OPTION ) )
822 {
823 Number priority = (Number) line.getValue( HOST_PRIORITY_OPTION, new Integer( -1 ) );
824 return priority.intValue();
825 }
826 else
827 {
828 return -1;
829 }
830 }
831
832 // ------------------------------------------------------------------------
833 // static utilities
834 // ------------------------------------------------------------------------
835
836 private static final DefaultOptionBuilder OPTION_BUILDER = new DefaultOptionBuilder();
837 private static final ArgumentBuilder ARGUMENT_BUILDER = new ArgumentBuilder();
838 private static final CommandBuilder COMMAND_BUILDER = new CommandBuilder();
839 private static final GroupBuilder GROUP_BUILDER = new GroupBuilder();
840 private static final NumberValidator INTERGER_VALIDATOR = NumberValidator.getIntegerInstance();
841 private static final Set HELP_TOPICS = new HashSet();
842
843 static
844 {
845 HELP_TOPICS.add( "add" );
846 HELP_TOPICS.add( "set" );
847 HELP_TOPICS.add( "remove" );
848 }
849
850 private static final Option DIRECTORY_OPTION =
851 OPTION_BUILDER
852 .withShortName( "dir" )
853 .withDescription( "Directory." )
854 .withRequired( false )
855 .withArgument(
856 ARGUMENT_BUILDER
857 .withDescription( "Directory." )
858 .withName( "path" )
859 .withMinimum( 1 )
860 .withMaximum( 1 )
861 .create() )
862 .create();
863
864 private static final Option SYSTEM_LIBRARY_OPTION =
865 OPTION_BUILDER
866 .withShortName( "system" )
867 .withDescription( "Local system repository." )
868 .withRequired( false )
869 .withArgument(
870 ARGUMENT_BUILDER
871 .withDescription( "Directory." )
872 .withName( "dir" )
873 .withMinimum( 1 )
874 .withMaximum( 1 )
875 .create() )
876 .create();
877
878 private static final Option PROFILE_URI_OPTION =
879 OPTION_BUILDER
880 .withShortName( "profile" )
881 .withDescription( "Configuration profile uri." )
882 .withRequired( false )
883 .withArgument(
884 ARGUMENT_BUILDER
885 .withDescription( "URI path." )
886 .withName( "uri" )
887 .withMinimum( 1 )
888 .withMaximum( 1 )
889 .withValidator( new URIValidator() )
890 .create() )
891 .create();
892
893 private static final Option HELP_COMMAND =
894 COMMAND_BUILDER
895 .withName( "help" )
896 .withDescription( "Print command help." )
897 .create();
898
899 private static final Option HOST_OPTION =
900 OPTION_BUILDER
901 .withShortName( "url" )
902 .withDescription( "Host URL." )
903 .withRequired( false )
904 .withArgument(
905 ARGUMENT_BUILDER
906 .withName( "url" )
907 .withMinimum( 1 )
908 .withMaximum( 1 )
909 .withValidator( new URLValidator() )
910 .create() )
911 .create();
912
913 private static final Option REQUIRED_HOST_OPTION =
914 OPTION_BUILDER
915 .withShortName( "url" )
916 .withDescription( "Host URL (required)." )
917 .withRequired( true )
918 .withArgument(
919 ARGUMENT_BUILDER
920 .withName( "url" )
921 .withMinimum( 1 )
922 .withMaximum( 1 )
923 .withValidator( new URLValidator() )
924 .create() )
925 .create();
926
927 private static final Option REQUIRED_CODEBASE_OPTION =
928 OPTION_BUILDER
929 .withShortName( "uri" )
930 .withDescription( "Codebase URI (required)." )
931 .withRequired( true )
932 .withArgument(
933 ARGUMENT_BUILDER
934 .withName( "uri" )
935 .withMinimum( 1 )
936 .withMaximum( 1 )
937 .withValidator( new URIValidator() )
938 .create() )
939 .create();
940
941 private static final Option CODEBASE_OPTION =
942 OPTION_BUILDER
943 .withShortName( "uri" )
944 .withDescription( "Codebase URI." )
945 .withRequired( false )
946 .withArgument(
947 ARGUMENT_BUILDER
948 .withName( "uri" )
949 .withMinimum( 1 )
950 .withMaximum( 1 )
951 .withValidator( new URIValidator() )
952 .create() )
953 .create();
954
955 private static final Option TITLE_OPTION =
956 OPTION_BUILDER
957 .withShortName( "title" )
958 .withDescription( "Title." )
959 .withRequired( false )
960 .withArgument(
961 ARGUMENT_BUILDER
962 .withName( "name" )
963 .withMinimum( 1 )
964 .withMaximum( 1 )
965 .create() )
966 .create();
967
968 private static final Option USERNAME_OPTION =
969 OPTION_BUILDER
970 .withShortName( "username" )
971 .withDescription( "Username." )
972 .withRequired( false )
973 .withArgument(
974 ARGUMENT_BUILDER
975 .withName( "username" )
976 .withMinimum( 1 )
977 .withMaximum( 1 )
978 .create() )
979 .create();
980
981 private static final Option PASSWORD_OPTION =
982 OPTION_BUILDER
983 .withShortName( "password" )
984 .withDescription( "Password." )
985 .withRequired( false )
986 .withArgument(
987 ARGUMENT_BUILDER
988 .withName( "password" )
989 .withMinimum( 1 )
990 .withMaximum( 1 )
991 .create() )
992 .create();
993
994 private static final Option HOST_PRIORITY_OPTION =
995 OPTION_BUILDER
996 .withShortName( "priority" )
997 .withDescription( "Host priority." )
998 .withRequired( false )
999 .withArgument(
1000 ARGUMENT_BUILDER
1001 .withName( "int" )
1002 .withMinimum( 1 )
1003 .withMaximum( 1 )
1004 .withValidator( INTERGER_VALIDATOR )
1005 .create() )
1006 .create();
1007
1008 private static final Option HOST_INDEX_OPTION =
1009 OPTION_BUILDER
1010 .withShortName( "index" )
1011 .withDescription( "Host index path." )
1012 .withRequired( false )
1013 .withArgument(
1014 ARGUMENT_BUILDER
1015 .withName( "resource" )
1016 .withMinimum( 1 )
1017 .withMaximum( 1 )
1018 .create() )
1019 .create();
1020
1021 private static final Option LAYOUT_OPTION =
1022 OPTION_BUILDER
1023 .withShortName( "layout" )
1024 .withDescription( "Host layout strategy." )
1025 .withRequired( false )
1026 .withArgument(
1027 ARGUMENT_BUILDER
1028 .withName( "id" )
1029 .withMinimum( 1 )
1030 .withMaximum( 1 )
1031 .create() )
1032 .create();
1033
1034 private static final Option HOST_SCHEME_OPTION =
1035 OPTION_BUILDER
1036 .withShortName( "scheme" )
1037 .withDescription( "Host authentication scheme." )
1038 .withRequired( false )
1039 .withArgument(
1040 ARGUMENT_BUILDER
1041 .withName( "scheme" )
1042 .withMinimum( 1 )
1043 .withMaximum( 1 )
1044 .create() )
1045 .create();
1046
1047 private static final Option HOST_PROMPT_OPTION =
1048 OPTION_BUILDER
1049 .withShortName( "prompt" )
1050 .withDescription( "Host authentication prompt." )
1051 .withRequired( false )
1052 .withArgument(
1053 ARGUMENT_BUILDER
1054 .withName( "prompt" )
1055 .withMinimum( 1 )
1056 .withMaximum( 1 )
1057 .create() )
1058 .create();
1059
1060 private static final Option TRUSTED_OPTION =
1061 OPTION_BUILDER
1062 .withShortName( "trusted" )
1063 .withDescription( "Assert as trusted host." )
1064 .withRequired( false )
1065 .create();
1066
1067 private static final Option UNTRUSTED_OPTION =
1068 OPTION_BUILDER
1069 .withShortName( "untrusted" )
1070 .withDescription( "Assert as untrusted host." )
1071 .withRequired( false )
1072 .create();
1073
1074 private static final Group TRUST_GROUP =
1075 GROUP_BUILDER
1076 .withMinimum( 0 )
1077 .withMaximum( 1 )
1078 .withOption( TRUSTED_OPTION )
1079 .withOption( UNTRUSTED_OPTION )
1080 .create();
1081
1082 private static final Option ENABLED_OPTION =
1083 OPTION_BUILDER
1084 .withShortName( "enabled" )
1085 .withDescription( "Enable the host." )
1086 .withRequired( false )
1087 .create();
1088
1089 private static final Option DISABLED_OPTION =
1090 OPTION_BUILDER
1091 .withShortName( "disabled" )
1092 .withDescription( "Disable the host." )
1093 .withRequired( false )
1094 .create();
1095
1096 private static final Group ENABLED_GROUP =
1097 GROUP_BUILDER
1098 .withMinimum( 0 )
1099 .withMaximum( 1 )
1100 .withOption( ENABLED_OPTION )
1101 .withOption( DISABLED_OPTION )
1102 .create();
1103
1104 private static final Option PROXY_EXCLUDE_OPTION =
1105 OPTION_BUILDER
1106 .withShortName( "excludes" )
1107 .withDescription( "Proxy excludes." )
1108 .withRequired( false )
1109 .withArgument(
1110 ARGUMENT_BUILDER
1111 .withName( "hosts" )
1112 .withMinimum( 1 )
1113 .withInitialSeparator( ' ' )
1114 .withSubsequentSeparator( ',' )
1115 .create() )
1116 .create();
1117
1118 private static final Group SET_HANDLER_OPTIONS_GROUP =
1119 GROUP_BUILDER
1120 .withMinimum( 0 )
1121 .withOption( CODEBASE_OPTION )
1122 .withOption( TITLE_OPTION )
1123 .create();
1124
1125 private static final Group ADD_HANDLER_OPTIONS_GROUP =
1126 GROUP_BUILDER
1127 .withOption( REQUIRED_CODEBASE_OPTION )
1128 .withOption( TITLE_OPTION )
1129 .create();
1130
1131 private static final Group SET_HOST_OPTIONS_GROUP =
1132 GROUP_BUILDER
1133 .withMinimum( 0 )
1134 .withOption( HOST_OPTION )
1135 .withOption( USERNAME_OPTION )
1136 .withOption( PASSWORD_OPTION )
1137 .withOption( HOST_PRIORITY_OPTION )
1138 .withOption( HOST_INDEX_OPTION )
1139 .withOption( ENABLED_GROUP )
1140 .withOption( TRUST_GROUP )
1141 .withOption( LAYOUT_OPTION )
1142 .withOption( HOST_SCHEME_OPTION )
1143 .withOption( HOST_PROMPT_OPTION )
1144 .create();
1145
1146 private static final Group ADD_HOST_OPTIONS_GROUP =
1147 GROUP_BUILDER
1148 .withMinimum( 0 )
1149 .withOption( REQUIRED_HOST_OPTION )
1150 .withOption( USERNAME_OPTION )
1151 .withOption( PASSWORD_OPTION )
1152 .withOption( HOST_PRIORITY_OPTION )
1153 .withOption( HOST_INDEX_OPTION )
1154 .withOption( DISABLED_OPTION )
1155 .withOption( TRUSTED_OPTION )
1156 .withOption( LAYOUT_OPTION )
1157 .withOption( HOST_SCHEME_OPTION )
1158 .withOption( HOST_PROMPT_OPTION )
1159 .create();
1160
1161 private static final Group PROXY_OPTIONS_GROUP =
1162 GROUP_BUILDER
1163 .withMinimum( 0 )
1164 .withOption( HOST_OPTION )
1165 .withOption( USERNAME_OPTION )
1166 .withOption( PASSWORD_OPTION )
1167 .withOption( PROXY_EXCLUDE_OPTION )
1168 .create();
1169
1170 private static final Group CACHE_OPTIONS_GROUP =
1171 GROUP_BUILDER
1172 .withMinimum( 0 )
1173 .withOption( DIRECTORY_OPTION )
1174 .withOption( LAYOUT_OPTION )
1175 .create();
1176
1177 private static final Group SYSTEM_OPTIONS_GROUP =
1178 GROUP_BUILDER
1179 .withMinimum( 0 )
1180 .withOption( DIRECTORY_OPTION )
1181 .withOption( LAYOUT_OPTION )
1182 .create();
1183
1184 private static final Option PROXY_COMMAND =
1185 COMMAND_BUILDER
1186 .withName( "proxy" )
1187 .withDescription( "Select proxy settings." )
1188 .withChildren( PROXY_OPTIONS_GROUP )
1189 .create();
1190
1191 private static final Option SET_CACHE_COMMAND =
1192 COMMAND_BUILDER
1193 .withName( "cache" )
1194 .withDescription( "Select cache settings." )
1195 .withChildren( CACHE_OPTIONS_GROUP )
1196 .create();
1197
1198 private static final Option SET_SYSTEM_COMMAND =
1199 COMMAND_BUILDER
1200 .withName( "system" )
1201 .withDescription( "Select system repository settings." )
1202 .withChildren( SYSTEM_OPTIONS_GROUP )
1203 .create();
1204
1205 private static final Option ADD_HOST_COMMAND =
1206 COMMAND_BUILDER
1207 .withName( "host" )
1208 .withDescription( "Add a new resource host." )
1209 .withChildren( ADD_HOST_OPTIONS_GROUP )
1210 .withArgument(
1211 ARGUMENT_BUILDER
1212 .withName( "id" )
1213 .withMinimum( 1 )
1214 .withMaximum( 1 )
1215 .create() )
1216 .create();
1217
1218 private static final Option SET_HOST_COMMAND =
1219 COMMAND_BUILDER
1220 .withName( "host" )
1221 .withDescription( "Resource host selection." )
1222 .withChildren( SET_HOST_OPTIONS_GROUP )
1223 .withArgument(
1224 ARGUMENT_BUILDER
1225 .withName( "id" )
1226 .withMinimum( 1 )
1227 .withMaximum( 1 )
1228 .create() )
1229 .create();
1230
1231 private static final Option SET_LAYOUT_COMMAND =
1232 COMMAND_BUILDER
1233 .withName( "layout" )
1234 .withDescription( "Layout scheme selection." )
1235 .withChildren( SET_HANDLER_OPTIONS_GROUP )
1236 .withArgument(
1237 ARGUMENT_BUILDER
1238 .withName( "id" )
1239 .withMinimum( 1 )
1240 .withMaximum( 1 )
1241 .create() )
1242 .create();
1243
1244 private static final Option SELECT_HOST_COMMAND =
1245 COMMAND_BUILDER
1246 .withName( "host" )
1247 .withDescription( "Resource host selection." )
1248 .withArgument(
1249 ARGUMENT_BUILDER
1250 .withName( "id" )
1251 .withMinimum( 1 )
1252 .withMaximum( 1 )
1253 .create() )
1254 .create();
1255
1256 private static final Option SELECT_LAYOUT_COMMAND =
1257 COMMAND_BUILDER
1258 .withName( "layout" )
1259 .withDescription( "Layout scheme selection." )
1260 .withArgument(
1261 ARGUMENT_BUILDER
1262 .withName( "id" )
1263 .withMinimum( 1 )
1264 .withMaximum( 1 )
1265 .create() )
1266 .create();
1267
1268 private static final Option ADD_LAYOUT_COMMAND =
1269 COMMAND_BUILDER
1270 .withName( "layout" )
1271 .withDescription( "Add a new layout." )
1272 .withChildren( ADD_HANDLER_OPTIONS_GROUP )
1273 .withArgument(
1274 ARGUMENT_BUILDER
1275 .withName( "id" )
1276 .withMinimum( 1 )
1277 .withMaximum( 1 )
1278 .create() )
1279 .create();
1280
1281 private static final Option REMOVE_PROXY_COMMAND =
1282 COMMAND_BUILDER
1283 .withName( "proxy" )
1284 .withDescription( "Delete proxy settings." )
1285 .create();
1286
1287 private static final Group ADD_OPTIONS_GROUP =
1288 GROUP_BUILDER
1289 .withMinimum( 1 )
1290 .withMinimum( 1 )
1291 .withOption( ADD_HOST_COMMAND )
1292 .withOption( ADD_LAYOUT_COMMAND )
1293 .create();
1294
1295 private static final Group SET_OPTIONS_GROUP =
1296 GROUP_BUILDER
1297 .withMinimum( 1 )
1298 .withMinimum( 1 )
1299 .withOption( PROXY_COMMAND )
1300 .withOption( SET_CACHE_COMMAND )
1301 .withOption( SET_SYSTEM_COMMAND )
1302 .withOption( SET_HOST_COMMAND )
1303 .withOption( SET_LAYOUT_COMMAND )
1304 .create();
1305
1306 private static final Group REMOVE_OPTIONS_GROUP =
1307 GROUP_BUILDER
1308 .withMinimum( 1 )
1309 .withMinimum( 1 )
1310 .withOption( SELECT_HOST_COMMAND )
1311 .withOption( SELECT_LAYOUT_COMMAND )
1312 .withOption( REMOVE_PROXY_COMMAND )
1313 .create();
1314
1315 private static final Option ADD_COMMAND =
1316 COMMAND_BUILDER
1317 .withName( "add" )
1318 .withChildren( ADD_OPTIONS_GROUP )
1319 .create();
1320
1321 private static final Option SET_COMMAND =
1322 COMMAND_BUILDER
1323 .withName( "set" )
1324 .withDescription( "Set an configuration aspect." )
1325 .withChildren( SET_OPTIONS_GROUP )
1326 .create();
1327
1328 private static final Option REMOVE_COMMAND =
1329 COMMAND_BUILDER
1330 .withName( "remove" )
1331 .withChildren( REMOVE_OPTIONS_GROUP )
1332 .create();
1333
1334 private static final Option INFO_COMMAND =
1335 COMMAND_BUILDER
1336 .withName( "info" )
1337 .withDescription( "List configuration." )
1338 .create();
1339
1340 private static final Option REVERT_COMMAND =
1341 COMMAND_BUILDER
1342 .withName( "revert" )
1343 .withDescription( "Set configuration to default." )
1344 .create();
1345
1346 private static final Option LOAD_COMMAND =
1347 COMMAND_BUILDER
1348 .withName( "load" )
1349 .withDescription( "Load a transit plugin." )
1350 .withArgument(
1351 ARGUMENT_BUILDER
1352 .withName( "uri" )
1353 .withMinimum( 1 )
1354 .withMaximum( 1 )
1355 .withValidator( new URIValidator() )
1356 .create() )
1357 .create();
1358
1359 private static final Option ARGUMENTS =
1360 ARGUMENT_BUILDER
1361 .withName( "args" )
1362 .create();
1363
1364 private static final Group COMMAND_GROUP =
1365 GROUP_BUILDER
1366 .withOption( INFO_COMMAND )
1367 .withOption( ADD_COMMAND )
1368 .withOption( SET_COMMAND )
1369 .withOption( REMOVE_COMMAND )
1370 .withOption( REVERT_COMMAND )
1371 .withOption( LOAD_COMMAND )
1372 .withOption( HELP_COMMAND )
1373 .withMinimum( 1 )
1374 .withMaximum( 1 )
1375 .create();
1376
1377 private static final Group OPTIONS_GROUP =
1378 GROUP_BUILDER
1379 .withName( "command" )
1380 .withOption( PROFILE_URI_OPTION )
1381 .withOption( COMMAND_GROUP )
1382 .withOption( ARGUMENTS )
1383 .withMinimum( 0 )
1384 .create();
1385
1386 private static CommandLine getCommandLine( Logger logger, String[] args )
1387 {
1388 try
1389 {
1390 // parse the command line arguments
1391
1392 Parser parser = new Parser();
1393 parser.setGroup( OPTIONS_GROUP );
1394 return parser.parse( args );
1395 }
1396 catch( OptionException e )
1397 {
1398 logger.error( e.getMessage() );
1399 return null;
1400 }
1401 }
1402
1403 private static void processHelp() throws IOException
1404 {
1405 processGeneralHelp( OPTIONS_GROUP );
1406 }
1407
1408 private static void processGeneralHelp( Group group ) throws IOException
1409 {
1410 HelpFormatter formatter = new HelpFormatter(
1411 HelpFormatter.DEFAULT_GUTTER_LEFT,
1412 HelpFormatter.DEFAULT_GUTTER_CENTER,
1413 HelpFormatter.DEFAULT_GUTTER_RIGHT,
1414 100, 50 );
1415
1416 formatter.getDisplaySettings().add( DisplaySetting.DISPLAY_GROUP_OUTER );
1417 formatter.getDisplaySettings().add( DisplaySetting.DISPLAY_PROPERTY_OPTION );
1418 formatter.getDisplaySettings().add( DisplaySetting.DISPLAY_ARGUMENT_BRACKETED );
1419
1420 formatter.getFullUsageSettings().add( DisplaySetting.DISPLAY_OPTIONAL );
1421 formatter.getFullUsageSettings().add( DisplaySetting.DISPLAY_GROUP_OUTER );
1422 formatter.getFullUsageSettings().add( DisplaySetting.DISPLAY_PROPERTY_OPTION );
1423 formatter.getFullUsageSettings().add( DisplaySetting.DISPLAY_OPTIONAL );
1424 formatter.getFullUsageSettings().add( DisplaySetting.DISPLAY_ARGUMENT_BRACKETED );
1425 formatter.getFullUsageSettings().remove( DisplaySetting.DISPLAY_PARENT_CHILDREN );
1426
1427 formatter.getLineUsageSettings().add( DisplaySetting.DISPLAY_PROPERTY_OPTION );
1428 formatter.getLineUsageSettings().add( DisplaySetting.DISPLAY_ARGUMENT_BRACKETED );
1429 formatter.getLineUsageSettings().remove( DisplaySetting.DISPLAY_PARENT_CHILDREN );
1430 formatter.getLineUsageSettings().remove( DisplaySetting.DISPLAY_GROUP_EXPANDED );
1431
1432 formatter.setGroup( group );
1433 formatter.setShellCommand( "transit" );
1434 formatter.print();
1435 }
1436 }
1437